﻿using System;
using GameFramework.Battle.Core;
using Gameplay.PVE.Utils;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
using Yoozoo.Mars.Got.SpriteAnim;
using Random = Unity.Mathematics.Random;

namespace Yoozoo.Gameplay.RTS
{
    //[BurstCompile]
    public struct SquareJob : IJobParallelFor
    {

        public int frameCount;

        public MarchSquareNativeData marchData;
        public ChildBehaviourNativeData childData;

        [ReadOnly]
        public NativeArray<float3> directions;

        //阵型相关
        //        [ReadOnly]
        //        public NativeArray<int> SoldierPositionIndexArray;
        //        [ReadOnly]
        //        public NativeArray<int> SoldierPositionIndexArray235to325;
        //        [ReadOnly]
        //        public NativeArray<int> SoldierPositionIndexArray135to180;
        //        [ReadOnly]
        //        public NativeArray<int> SoldierPositionIndexArray45To135Degree;

        [ReadOnly]
        public NativeArray<int> SoldierPositionIndexArrays;

        [ReadOnly]
        public NativeArray<int> localPositionIndex;
        [ReadOnly]
        public NativeArray<float3> normalPositions;
        [ReadOnly]
        public NativeArray<float3> battlePositions;


        //战斗相关
        [ReadOnly]
        public NativeHashMap<int, SoldierAttackActionConfigData> attackActionConfigs;
        [ReadOnly]
        public NativeHashMap<int, AttackActionConfigData> attackActions;
        [ReadOnly]
        public NativeArray<int> useActionIds;
        [ReadOnly]
        public NativeArray<AttackActionInfoData> actionInfos;

        public float realTime;
        public Random random;

        private const int Enum_MarchState_Park = 0;
        private const int Enum_MarchState_Move = 1;
        private const int Enum_MarchState_Attack = 2;
        private const int Enum_MarchState_DIE = 3;
        private const int Enum_MarchState_PlyDIEIdle = 4;
        private const int Enum_MarchState_ClientAttack = 7;

        private const int Enum_MarchState_ExternalMovement = 8;
        //小兵状态机
        private const int Enum_ChildState_Idle = 0;
        private const int Enum_ChildState_Move = 1;
        private const int Enum_ChildState_Attack = 2;
        private const int Enum_ChildState_ReadyToDead = 3;
        private const int Enum_ChildState_Dead = 4;
        private const int Enum_ChildState_Escape = 5;
        private const int Enum_ChildState_PlayDeadAnim = 6;
        private const int Enum_ChildState_ExternalMovement = 6;

        //小兵攻击子状态
        private const int Enum_ChildAttackSubState_Init = -1;
        private const int Enum_ChildAttackSubState_Move = 0;
        private const int Enum_ChildAttackSubState_MoveFinished = 1;
        private const int Enum_ChildAttackSubState_WaitAttack = 2;
        private const int Enum_ChildAttackSubState_ReadSubActionConfig = 3;
        private const int Enum_ChildAttackSubState_ExecSubAction = 4;
        private const int Enum_ChildAttackSubState_FinishSubCircleState = 5;

        //小兵死亡子状态
        private const int Enum_ChilsDeadSubState_DelayDead = -1;
        private const int Enum_ChilsDeadSubState_KnockBack = 0;
        private const int Enum_ChilsDeadSubState_Fade = 1;
        private const int Enum_ChilsDeadSubState_Destroy = 2;

        private const float Const_AttackTransformTimeMax = 1.5f;
        private const float Const_AttackTrasnformDistanceMax = 0.6f;
        private const float Const_AttackTransformChildSpeed = Const_AttackTrasnformDistanceMax / Const_AttackTransformTimeMax;

        public void Execute(int i)
        {
            if (!marchData.valid[i])
            {
                return;
            }

            #region 获取方阵数据变量

#if UNITY_EDITOR
            var marchId = marchData.marchId[i];
#else
            ulong marchId = 111;  
#endif
            var childCount = marchData.childCount[i];
            var childIndexHead = marchData.childIndexHead[i];
            var squareStartPosition = marchData.squareStartPosition[i];
            var squareEndPosition = marchData.squareEndPosition[i];
            var segmentStartTime = marchData.segmentStartTime[i];
            var squareForward = marchData.forward[i];
            var squareMoveForward = squareEndPosition - squareStartPosition;
            squareMoveForward = squareForward;
            var squarePosition = marchData.position[i];
            var needRefresh = false;//marchData.needCalculateChildren[i];
            var currentSegmentDuration = marchData.currentSegmentDuration[i];
            var formationId = marchData.formationId[i];
            var TurnState = marchData.TurnState[i];
            var formationPositionIndexOffset = marchData.formationPositionIndexOffset[i];
            marchData.TurnState[i] = -1;
            var speed = marchData.speed[i];
            if (speed == 0)
            {
                speed = 1000;
            }
            var forceMoveChildren = marchData.needForceMoveChildren[i];
            if (forceMoveChildren)
            {
                marchData.needForceMoveChildren[i] = false;
            }
            //方针状态
            var marchStatus = marchData.status[i];
            var InAdjustPositionState = false;
            var changeStatusFlag = marchData.changeStatusFlag[i];
            var isServerPosChange = marchData.isServerPosChange[i];
            if (isServerPosChange)
            {
                marchData.isServerPosChange[i] = false;
            }
            if (changeStatusFlag)
            {
                marchData.changeStatusFlag[i] = false;
                InAdjustPositionState = true;//marchStatus != Enum_ChildState_Idle;
                needRefresh = true;  //这个逻辑是只有改变状态才刷新，但其实不止，比如从后台切回来，如果状态没变，岂不是不会走刷新逻辑了
            }

            var alpha = marchData.alpha[i];
            var squareOverrideAlpha = marchData.overrideAlpha[i];
            marchData.overrideAlpha[i] = false;
            int squareDirectionIndex = 0;
            var squareDirection = GetFixedDirectionByForward(squareForward, ref squareDirectionIndex);
            int squareMoveDirectionIndex = 0;
            var squareMoveDirection = GetFixedDirectionByForward(squareMoveForward, ref squareMoveDirectionIndex);
            int childDirectionIndex = squareDirectionIndex;
            /*if (squareEndPosition != squareStartPosition)
            {
                GetFixedDirectionByForward(squareEndPosition - squareStartPosition, ref childDirectionIndex);
            }*/
            var isBesiege = marchData.isBesiege[i];
            var isClientInBattle = marchData.isClientInBattle[i];

            #endregion

            #region UpdateChildren 
            for (int j = childIndexHead; j < childIndexHead + childCount; j++)
            {
                if (!childData.valid[j])
                {
                    continue;
                }

                var childIndex = childData.index[j];
                var PosIndex = childData.postionIndex[j];
                // 强制刷新位置
                if (forceMoveChildren)
                {
                    childData.position[j] = squarePosition + GetUnitInSquarePositionOffset(PosIndex, squareForward, formationId, childCount, TurnState, out int finalPosIndex, formationPositionIndexOffset, isClientInBattle, i);
                    childData.postionIndex[j] = finalPosIndex;
                    childData.forward[j] = squareDirection;
                    childData.direction[j] = squareDirectionIndex;
                    childData.targetDirection[j] = squareDirectionIndex;
                    childData.rotateStartTime[j] = 0;
                    if (marchStatus != Enum_MarchState_Move && marchStatus != Enum_MarchState_DIE)
                    {
                        childData.moveNeedTime[j] = 0;
                    }
                }


                bool forceAdjustPosition = false;
                int childState = marchStatus;
                if (changeStatusFlag)
                {
                    //处理行军状态
                    bool childChangeStatus = CanChildChangeStatus(childData.state[j]);
                    if (marchStatus == Enum_MarchState_Park)
                    {
                        if (childData.moveNeedTime[j] > 0 || isServerPosChange)
                        {
                            childState = Enum_ChildState_Move;
                            forceAdjustPosition = true;
                            squareMoveDirectionIndex = squareDirectionIndex;
                            //squareMoveForward = squareDirection;
                        }
                    }
                    else if (marchStatus == Enum_MarchState_Move || marchStatus == Enum_MarchState_DIE)
                    {
                        childData.InAdjustPositionState[j] = true;
                        forceAdjustPosition = true;
                        childState = Enum_ChildState_Move;
                    }
                    else if (marchStatus == Enum_MarchState_Attack)
                    {
                        if (isServerPosChange && !isClientInBattle)
                        {
                            childState = Enum_ChildState_Move;
                            forceAdjustPosition = true;
                            squareMoveDirectionIndex = squareDirectionIndex;
                            //squareMoveForward = squareDirection;
                        }
                        else if (childData.state[j] == Enum_ChildState_Idle || childData.state[j] == Enum_MarchState_ClientAttack || childData.state[j] == Enum_ChildState_Move)
                        {
                            childData.subState[j] = -1;
                            childData.instructionSetIndex[j] = 0;
                            childData.actionIndex[j] = 0;
                            childData.rotateStartTime[j] = 0;
                        }
                        else
                        {
                            childChangeStatus = false;
                        }
                        childData.InAdjustPositionState[j] = true;
                    }
                    else if (marchStatus == Enum_MarchState_ClientAttack)
                    {
                        childState = Enum_MarchState_ClientAttack;
                        childData.subState[j] = Enum_ChildAttackSubState_Init;
                    }
                    else if (marchStatus == Enum_MarchState_PlyDIEIdle)
                    {
                        childState = Enum_ChildState_PlayDeadAnim;
                    }
                    else if (marchStatus == Enum_MarchState_ExternalMovement)
                    {
                        childState = Enum_ChildState_ExternalMovement;
                    }
                    if (childChangeStatus)
                    {
                        childData.state[j] = childState;
                    }
                }


                {
                    if (marchId == MarchSequareConstant.DebugUid)
                    {
                        UnityEngine.Debug.Log($" framecount:{frameCount} {marchId}-{childIndex} forceMoveChildren = {forceMoveChildren}  changeStatusFlag = {changeStatusFlag}  state = {childData.state[j]}");

                    }

                }

                var overrideAlpha = squareOverrideAlpha;
                var playAction = EAnimationType.none;
                float actionSpeed = MarchSequareConstant.NormalSpriteSpeed;
                bool changeSpeedFlag = false;
                int originTargetDirection = childData.targetDirection[j];
                int targetDirection = originTargetDirection;
                int direction = 0;
                bool positionChanged = false;
                Vector3 childPosition = Vector3.zero;
                var visible = true;

                #region ChildStateAction

                if (childData.state[j] == Enum_ChildState_ExternalMovement)
                {
                    #region UpdateExternalMovement
                    if (changeStatusFlag)
                    {
                        playAction = EAnimationType.ani_Run;
                        positionChanged = true;
                        childPosition = squarePosition + GetUnitInSquarePositionOffset(PosIndex, squareForward, formationId, childCount, TurnState, out int finalPosIndex, formationPositionIndexOffset, isClientInBattle, i);
                        childData.postionIndex[j] = finalPosIndex;
                        direction = squareDirectionIndex;
                        actionSpeed = Random(j, 0.8f, 1.2f);
                        changeSpeedFlag = true;
                    }
                    #endregion
                }
                else if (childData.state[j] == Enum_ChildState_Idle)
                {
                    //idle
                    //==============更新位置
                    #region UpdateIdle
                    if (changeStatusFlag)
                    {
                        playAction = EAnimationType.ani_Stand_Idle;
                        positionChanged = true;
                        childPosition = squarePosition + GetUnitInSquarePositionOffset(PosIndex, squareForward, formationId, childCount, TurnState, out int finalPosIndex, formationPositionIndexOffset, isClientInBattle, i);
                        childData.postionIndex[j] = finalPosIndex;
                        direction = squareDirectionIndex;
                        actionSpeed = Random(j, 0.8f, 1.2f);
                        changeSpeedFlag = true;
                    }
                    #endregion
                }
                else if (childData.state[j] == Enum_ChildState_Move)
                {
                    //小兵在移动
                    #region UpdateMovement

                    if (marchId == MarchSequareConstant.DebugUid)
                    {
                        // Debug.Log($" framecount:{frameCount} {marchId}-{childIndex}  是否需要needRefresh: {needRefresh} " +
                        //                         $"squareStartPosition：{squareStartPosition} squareEndPosition：{squareEndPosition} ");
                    }

                    playAction = EAnimationType.ani_Run;
                    // 如果位置和方向都跟之前缓存的不一样了，或者第一段走完了；  那么重新计算位置和方向等
                    if (needRefresh)
                    {
                        //小兵当前位置
                        var index = PosIndex;
                        if (marchStatus == Enum_MarchState_DIE)
                        {
                            index = childIndex;
                            TurnState = -1;
                        }
                        float3 offset = GetUnitInSquarePositionOffset(index, squareMoveForward, formationId, childCount, TurnState, out int finalPosIndex, formationPositionIndexOffset, isClientInBattle, i);
                        childData.postionIndex[j] = finalPosIndex;
                        float3 rightUnitPos = squarePosition + offset;
                        var offPosDis = math.distance(rightUnitPos, childData.position[j]); //当前小兵显示位置 与 正确的方阵之间的距离
                        if (offPosDis > MarchSequareConstant.DeviationDistance && childData.soldierId[j] == -200) //只有侦察兵生效
                        {
                            if (marchId == MarchSequareConstant.DebugUid && childIndex == 0)
                            {
                                //Debug.Log($" framecount:{frameCount}  {marchId}-{childIndex}  差距过大{offPosDis}，使用方阵真位置");
                            }
                            childData.startMovePosition[j] = rightUnitPos;//用正确的
                            childData.InAdjustPositionState[j] = false;
                        }
                        else
                        {
                            if (marchId == MarchSequareConstant.DebugUid && childIndex == 0)
                            {
                                // Debug.Log($" {marchId}-{childIndex}  差距{offPosDis}，使用当前值");
                            }
                            childData.startMovePosition[j] = childData.position[j];
                            childData.InAdjustPositionState[j] = (currentSegmentDuration > 0.5f || forceAdjustPosition);
                        }
                        // 为了转阵型； 将阵型调整到目标方向上，然后同向移动
                        if (childData.InAdjustPositionState[j])
                        {
                            childData.IsFirstChange[j] = false;
                            //private void calcuAdjustSquarePosArgu
                            //方阵当前的位置
                            float3 marchSquareCurrentPosition = squarePosition;
                            // Vector3 offset = GetUnitInSquarePositionOffset(childIndex,squareMoveForward,formationId,childCount,isMirror);
                            float3 currentSoldierPos = childData.startMovePosition[j];
                            /*if (!childData.transformOffset[j].Equals(Vector3.zero))
                            {
                                currentSoldierPos =  marchSquareCurrentPosition + offset;
                            }*/
                            //先假设0.3距离内变阵成功，那么大家需要走多远，越远的那个，就按照比例调整的更远，造成越远的越最后调整完
                            var minChangePosDistance = 0.3f;
                            var needMoveDistance = minChangePosDistance;
                            float moveDistance = 0;

                            var delayTime = 0f;
                            if (marchStatus == Enum_MarchState_Park)
                            {
                                var endPosition = squareEndPosition + offset;
                                needMoveDistance = Vector3.Distance(endPosition,
                                    childData.position[j]);
                                targetDirection = squareMoveDirectionIndex;
                                childData.targetMovePosition[j] = endPosition;
                            }
                            else
                            {
                                childData.targetMovePosition[j] = marchSquareCurrentPosition + minChangePosDistance *
                                                                  math.normalizesafe(squareMoveForward) + offset;
                                float mga = math.length(childData.targetMovePosition[j] - currentSoldierPos);

                                minChangePosDistance = mga * MarchSequareConstant.minChangePosDistanceFactor;

                                minChangePosDistance = Mathf.Min(minChangePosDistance, math.length(squareEndPosition - marchSquareCurrentPosition));
                                var squareP = marchSquareCurrentPosition + minChangePosDistance * math.normalizesafe(squareMoveForward);
                                //算一个新的位置
                                childData.targetMovePosition[j] = squareP + offset;
                                //if (childData.moveNeedTime[j] == 0)
                                {
                                    //delayTime = Vector3.Distance(squareP,childData.position[j]);
                                    //delayTime = Mathf.Clamp(delayTime, 0,0.5f);
                                }
                                childData.targetMovePosition[j] = childData.targetMovePosition[j] + speed * delayTime * math.normalizesafe(squareMoveForward);
                                if (minChangePosDistance > MarchSequareConstant.minRotationDistance)
                                {
                                    var targetForward = childData.targetMovePosition[j] - childData.startMovePosition[j];
                                    GetFixedDirectionByForward(targetForward, ref targetDirection);
                                    moveDistance = ((Vector3)targetForward).magnitude;
                                }
                                else
                                {
                                    targetDirection = squareMoveDirectionIndex;
                                    moveDistance = 1;
                                }
                                needMoveDistance = minChangePosDistance;
                            }

                            childData.InAdjustPositionState[j] = true;


                            /*if (!childData.transformOffset[j].Equals(offset))
                            {
                                childData.transformOffset[j] = offset;
                            }*/

                            //小兵需要移动的距离
                            childData.moveNeedTime[j] = needMoveDistance / speed;//Mathf.Min(needMoveDistance / speed,currentSegmentDuration);
                                                                                 //动画播放速度
                            actionSpeed = (moveDistance / childData.moveNeedTime[j]) / speed;
                            actionSpeed = Mathf.Clamp(actionSpeed, MarchSequareConstant.MoveSpriteSpeed, MarchSequareConstant.MoveSpriteSpeedMax);
                            changeSpeedFlag = true;
                            childData.moveStartTime[j] = realTime + delayTime;
                            //childData.rotateStartTime[j] = realTime;
                            if (marchId == MarchSequareConstant.DebugUid && childIndex == 0)
                            {
                                // Debug.Log($" framecount:{frameCount} {marchId}-{childIndex} 调整方阵计算  childData.startMovePosition：{childData.startMovePosition[j]} childData.targetMovePosition：{childData.targetMovePosition[j]} " +
                                //                         $"segmentStartTime = {segmentStartTime}  currentSegmentDuration = {currentSegmentDuration}  ");
                            }
                        }
                        else
                        {
                            //private calcuMoveArgu
                            if (!MarchSequareConstant.originPosRotation)
                            {
                                childData.rotateStartTime[j] = 0;
                                childData.startMovePosition[j] = squareStartPosition + offset;
                                //小兵在方阵中的最终位置
                                childData.targetMovePosition[j] = squareEndPosition + offset;
                                //childData.targetForward[j] = normalizedSquareForward;
                                childData.moveStartTime[j] = segmentStartTime;
                                // 小兵要移动的距离
                                childData.moveNeedTime[j] = currentSegmentDuration;
                                childData.InAdjustPositionState[j] = false;
                                targetDirection = squareMoveDirectionIndex;
                                actionSpeed = MarchSequareConstant.MoveSpriteSpeed * Random(j, 0.8f, 1.2f);
                                changeSpeedFlag = true;
                                if (marchId == MarchSequareConstant.DebugUid)
                                {
                                    // Debug.Log($" framecount:{frameCount} {marchId}-{childIndex} 正常计算时间位置  childData.startMovePosition：{childData.startMovePosition[j]} childData.targetMovePosition：{childData.targetMovePosition[j]} " +
                                    //                     $"segmentStartTime = {segmentStartTime}  currentSegmentDuration = {currentSegmentDuration}  ");
                                }
                            }
                        }
                        playAction = EAnimationType.ani_Run;
                    }
                    if (childData.InAdjustPositionState[j])
                    {
                        //走位
                        if (childData.moveNeedTime[j] == 0)//变阵结束了
                        {
                            childData.InAdjustPositionState[j] = false;
                            //private calcuMoveArgu
                            if (!MarchSequareConstant.originPosRotation)
                            {
                                float3 offset = GetUnitInSquarePositionOffset(PosIndex, squareMoveForward, formationId, childCount, TurnState, out int finalPosIndex, formationPositionIndexOffset, isClientInBattle, i);
                                childData.postionIndex[j] = finalPosIndex;
                                childData.startMovePosition[j] = squareStartPosition + offset;
                                //小兵在方阵中的最终位置
                                childData.targetMovePosition[j] = squareEndPosition + offset;
                                targetDirection = squareMoveDirectionIndex;
                                childData.moveStartTime[j] = segmentStartTime;
                                // 小兵要移动的距离
                                childData.InAdjustPositionState[j] = false;
                                childData.moveNeedTime[j] = currentSegmentDuration;
                                actionSpeed = MarchSequareConstant.MoveSpriteSpeed * Random(j, 0.8f, 1.2f);
                                changeSpeedFlag = true;
                            }
                        }
                    }
                    else
                    {
                        targetDirection = squareMoveDirectionIndex;
                    }

                    if (childData.moveNeedTime[j] == 0 && childData.soldierId[j] != -200) //侦察小兵没有停止动作
                    {
                        childData.state[j] = Enum_ChildState_Idle;
                        playAction = EAnimationType.ani_Stand_Idle;
                        targetDirection = squareDirectionIndex;
                    }

                    #endregion
                }
                else if (childData.state[j] == Enum_ChildState_Attack)
                {
                    //战斗
                    #region UpdateBattle
                    // -1：攻击前(可能要先移动），0 准备进入，等待阶段  1：读取配置阶段 2：执行指令阶段 3： 结束阶段
                    var subState = childData.subState[j];
                    if (isServerPosChange)
                    {
                        subState = -1;
                        childData.stageStartTime[j] = realTime;
                    }

                    bool needAdjustUnitPos = false;
                    if (subState == Enum_ChildAttackSubState_Init)//init
                    {
                        childData.startMovePosition[j] = childData.position[j];
                        //计算小兵需要的攻击位置
                        var attackPosition = GetUnitInSquarePositionOffset(PosIndex, squareForward, formationId, childCount, TurnState, out int finalPosIndex, formationPositionIndexOffset, true, i) + squarePosition;
                        childData.postionIndex[j] = finalPosIndex;
                        childData.targetMovePosition[j] = attackPosition;
                        //是否需要先移动到攻击点
                        var diff = attackPosition - childData.position[j];
                        var childSpeed = Const_AttackTransformChildSpeed;//speed * 0.9f;
                        if (childSpeed == 0)
                        {
                            childSpeed = 0.002166667f * 2;  // 服务器用的这个； //TODO:用浮点数
                        }
                        var diffDistance = math.lengthsq(diff);
                        if (diffDistance > MarchSequareConstant.ChildUnitDeviationDistance)
                        {
                            needAdjustUnitPos = false;
                            positionChanged = true;
                            childPosition = attackPosition;
                        }
                        else //if (diffDistance > childSpeed * childSpeed && (Mathf.Abs(diff.x) >0 || Mathf.Abs(diff.z) > 0))
                        {
                            var currentPosition = childData.position[j];
                            var f = attackPosition - currentPosition;
                            var moveDuration = 0f;
                            //if (isBesiege)
                            {
                                moveDuration = math.length(f) / childSpeed * 1f;
                            }
                            /*else
                            {
                                moveDuration = f.magnitude / childSpeed / 30;
                            }*/
                            //限制变阵的最长时间
                            /*if (moveDuration > 2)
                            {
                                moveDuration = 2 * Random(j,0.8f,1.2f);
                            }*/
                            childData.moveNeedTime[j] = moveDuration;
                            childData.moveStartTime[j] = realTime;
                            childData.rotateStartTime[j] = 0;
                            GetFixedDirectionByForward(f, ref targetDirection);
                            needAdjustUnitPos = true;
                        }

                        if (needAdjustUnitPos)
                        {
                            playAction = EAnimationType.ani_Run;
                            subState = Enum_ChildAttackSubState_Move;
                        }
                        else
                        {
                            childData.moveNeedTime[j] = 0;
                            subState = Enum_ChildAttackSubState_MoveFinished;
                        }
                    }
                    else if (subState == Enum_ChildAttackSubState_Move)//move
                    {
                        if (childData.moveNeedTime[j] == 0 && childData.rotateStartTime[j] == 0)//说明移动结束，切换状态
                        {
                            playAction = EAnimationType.ani_Stand_Idle;
                            subState = Enum_ChildAttackSubState_MoveFinished;
                        }
                        else
                        {
                            playAction = EAnimationType.ani_Run;
                        }
                    }
                    //如果该兵种没有攻击配置就返回，(x??

                    if (childData.actionConfigId[j] >= 0)
                    {
                        targetDirection = squareDirectionIndex;
                        childData.rotateStartTime[j] = 0;
                        var actionConfigs = attackActionConfigs[childData.actionConfigId[j]];
                        if (subState == Enum_ChildAttackSubState_MoveFinished)//moveFinished
                        {
                            //选取一个指令集
                            var actionIdHead = actionConfigs.useActionIdHead;
                            var actionIdLength = actionConfigs.useActionIdLength;
                            //开始指令集索引随机
                            childData.instructionSetIndex[j] = random.NextInt(actionIdLength);
                            childData.stageStartTime[j] = realTime;
                            childData.waitTime[j] = Random(j, 0, 0.5f);
                            if (childData.waitTime[j] > 0)
                            {
                                subState = Enum_ChildAttackSubState_WaitAttack;
                                if (playAction != EAnimationType.ani_Stand_Shoot_Process)
                                {
                                    playAction = EAnimationType.ani_Stand_Idle;
                                }
                            }
                            else
                            {
                                subState = Enum_ChildAttackSubState_ReadSubActionConfig;
                            }
                        }
                        else if (subState == Enum_ChildAttackSubState_WaitAttack)//WaitAttack
                        {
                            float wt = realTime - childData.stageStartTime[j];
                            if (wt >= childData.waitTime[j])
                            {
                                subState = Enum_ChildAttackSubState_ReadSubActionConfig;
                            }
                        }
                        else if (subState == Enum_ChildAttackSubState_ReadSubActionConfig)//readConfig
                        {
                            var instructIndex = childData.instructionSetIndex[j] + 1;
                            if (instructIndex >= actionConfigs.useActionIdLength)
                            {
                                instructIndex = 0;
                            }
                            childData.instructionSetIndex[j] = instructIndex;
                            childData.stageStartTime[j] = realTime;
                            childData.actionIndex[j] = 0;
                            subState = Enum_ChildAttackSubState_ExecSubAction;
                        }
                        else if (subState == Enum_ChildAttackSubState_ExecSubAction) //ExecSubAction
                        {
                            var actionId = useActionIds[actionConfigs.useActionIdHead + childData.instructionSetIndex[j]];
                            var instructionSet =
                                attackActions[actionId];
                            var subActionHead = instructionSet.actionsHead;
                            var subAction = actionInfos[subActionHead + childData.actionIndex[j]];
                            playAction = subAction.animType;
                            // 阶段时间是跟动画时间挂钩的，如果动画跑的快，那么阶段时间在外面的时间线也会短
                            float actionDuration = realTime - childData.stageStartTime[j];
                            if (actionDuration >=
                                subAction.time / MarchSequareConstant.AnimatorSpeed)  //是否大于配置的指令时间
                            {
                                childData.stageStartTime[j] = realTime;
                                childData.actionIndex[j]++;
                                //超出当前指令集范围
                                if (childData.actionIndex[j] >= instructionSet.actionsLength)
                                {
                                    childData.subState[j] = Enum_ChildAttackSubState_FinishSubCircleState;
                                    childData.actionIndex[j] = 0;
                                }
                            }
                        }
                        else if (subState == Enum_ChildAttackSubState_FinishSubCircleState) //finish
                        {
                            childData.subState[j] = Enum_ChildAttackSubState_MoveFinished;
                            childData.stageStartTime[j] = realTime;
                        }
                    }

                    childData.subState[j] = subState;

                    #endregion
                }
                else if (childData.state[j] == Enum_ChildState_ReadyToDead)
                {
                    childData.state[j] = Enum_ChildState_Dead;
                    childData.subState[j] = Enum_ChilsDeadSubState_DelayDead;

                    childData.stageStartTime[j] = realTime + Random(j, 0, 1f);
                }
                else if (childData.state[j] == Enum_ChildState_Dead)
                {
                    var subState = childData.subState[j];
                    if (subState == Enum_ChilsDeadSubState_Destroy)//destroy
                    {
                        //销毁
                        //m_unit.RemoveModel(); 
                        //m_unit.IsInTimeline = false;
                        visible = false;
                    }
                    else if (subState == Enum_ChilsDeadSubState_DelayDead) // 等待状态
                    {
                        if (realTime >= childData.stageStartTime[j])
                        {
                            if (true)
                            {
                                childData.subState[j] = Enum_ChilsDeadSubState_KnockBack;
                                childData.startMovePosition[j] = childData.position[j];
                                childData.moveNeedTime[j] = 0;
                            }
                            else
                            {
                                childData.subState[j] = Enum_ChilsDeadSubState_Fade;
                            }
                            playAction = EAnimationType.ani_Dead;
                            childData.stageStartTime[j] = realTime;

                        }
                    }
                    else if (subState == Enum_ChilsDeadSubState_KnockBack)  //击倒状态
                    {
                        var knockBackHorizontalForward = -childData.forward[j];
                        var passedTime = realTime - childData.stageStartTime[j];
                        var verticalStartSpeed = 2f;
                        var verticalA = -10;
                        var horizontalDistance = 0.3f;
                        var vt = verticalStartSpeed + passedTime * verticalA;
                        var y = (vt * vt - verticalStartSpeed * verticalStartSpeed) / 2 / verticalA;
                        var totalTime = Math.Abs(verticalStartSpeed / (float)verticalA * 2);
                        if (passedTime >= totalTime)
                        {
                            passedTime = totalTime;
                            childData.subState[j] = Enum_ChilsDeadSubState_Fade;
                            childData.stageStartTime[j] = realTime;
                        }
                        var horizontalMove = passedTime / totalTime * horizontalDistance;
                        positionChanged = false;
                        var newPosition = childData.startMovePosition[j] +
                                          horizontalMove * math.normalizesafe(knockBackHorizontalForward) +
                                          new float3(0, y, 0);
                        childData.position[j] = newPosition;
                    }
                    else if (subState == Enum_ChilsDeadSubState_Fade)  // 死亡渐隐阶段
                    {
                        var fadeTime = 2;
                        var percent = (realTime - childData.stageStartTime[j]) / fadeTime;
                        if (percent < 1)
                        {
                            alpha = 1 - percent;
                            overrideAlpha = true;
                        }
                        else
                        {
                            alpha = 0;
                            overrideAlpha = true;
                            childData.subState[j] = Enum_ChilsDeadSubState_Destroy;
                        }
                    }
                }
                else if (childData.state[j] == Enum_ChildState_Escape)
                {
                    //第一阶段，确定逃跑方向，渐隐开始时间，开始四散而逃
                    if (childData.subState[j] == 0)
                    {
                        var p = childData.position[j];
                        var f = math.normalizesafe(p - squarePosition);
                        var moveTime = Random(j, 1, 3);
                        var moveSpeed = Random(j, 2f, 3f);
                        childData.startMovePosition[j] = p;
                        childData.targetMovePosition[j] = p + moveTime * f * speed * moveSpeed;
                        actionSpeed = moveSpeed;
                        changeSpeedFlag = true;
                        GetFixedDirectionByForward(f, ref targetDirection);
                        childData.moveNeedTime[j] = moveTime;
                        childData.moveStartTime[j] = realTime;
                        childData.subState[j] = 1;
                        alpha = 1;
                        overrideAlpha = true;
                        playAction = EAnimationType.ani_Run;
                    }
                    else if (childData.subState[j] == 1)
                    {
                        var passedTime = realTime - childData.moveStartTime[j];
                        if (passedTime >= childData.moveNeedTime[j])
                        {
                            visible = false;
                            childData.subState[j] = 2;
                        }
                        if (passedTime >= childData.moveNeedTime[j] - 1)
                        {
                            alpha = childData.moveNeedTime[j] - passedTime;
                            overrideAlpha = true;
                        }

                    }
                }
                else if (childData.state[j] == Enum_MarchState_ClientAttack)
                {

                    var subState = childData.subState[j];
                    bool needAdjustUnitPos = false;
                    if (subState == Enum_ChildAttackSubState_Init)//init
                    {
                        childData.startMovePosition[j] = childData.position[j];
                        //计算小兵需要的攻击位置
                        var attackPosition = GetUnitInSquarePositionOffset(PosIndex, squareForward, formationId, childCount, TurnState, out int finalPosIndex, formationPositionIndexOffset, false, i) + squarePosition;
                        childData.postionIndex[j] = finalPosIndex;
                        childData.targetMovePosition[j] = attackPosition;
                        //是否需要先移动到攻击点
                        var diff = attackPosition - childData.position[j];
                        var childSpeed = Const_AttackTransformChildSpeed;//speed * 0.9f;
                        if (childSpeed == 0)
                        {
                            childSpeed = 0.002166667f * 2;  // 服务器用的这个； //TODO:用浮点数
                        }
                        var diffDistance = math.lengthsq(diff);
                        if (diffDistance > MarchSequareConstant.ChildUnitDeviationDistance)
                        {
                            needAdjustUnitPos = false;
                            positionChanged = true;
                            childPosition = attackPosition;
                        }
                        else //if (diffDistance > childSpeed * childSpeed && (Mathf.Abs(diff.x) >0 || Mathf.Abs(diff.z) > 0))
                        {
                            var currentPosition = childData.position[j];
                            var f = attackPosition - currentPosition;
                            var moveDuration = math.length(f) / childSpeed * 1f;
                            childData.moveNeedTime[j] = moveDuration;
                            childData.moveStartTime[j] = realTime;
                            childData.rotateStartTime[j] = 0;
                            GetFixedDirectionByForward(f, ref targetDirection);
                            needAdjustUnitPos = true;
                        }

                        if (needAdjustUnitPos)
                        {
                            playAction = EAnimationType.ani_Run;
                            subState = Enum_ChildAttackSubState_Move;
                        }
                        else
                        {
                            childData.moveNeedTime[j] = 0;
                            subState = Enum_ChildAttackSubState_MoveFinished;
                        }
                    }
                    else if (subState == Enum_ChildAttackSubState_Move)//move
                    {
                        if (childData.moveNeedTime[j] == 0 && childData.rotateStartTime[j] == 0)//说明移动结束，切换状态
                        {
                            playAction = EAnimationType.ani_Stand_Shoot_Process;
                            subState = Enum_ChildAttackSubState_MoveFinished;
                        }
                        else
                        {
                            playAction = EAnimationType.ani_Run;
                        }
                    }
                    else if (subState == Enum_ChildAttackSubState_MoveFinished)
                    {
                        playAction = EAnimationType.ani_Stand_Shoot_Process;
                    }
                    targetDirection = squareDirectionIndex;
                    childData.rotateStartTime[j] = 0;

                    childData.subState[j] = subState;
                }
                else if (childData.state[j] == Enum_ChildState_PlayDeadAnim)
                {
                    playAction = EAnimationType.ani_Dead;
                }
                #endregion

                #region UpdateForward
                UpdateForward(originTargetDirection, ref targetDirection, j);
                #endregion

                #region UpdatePosition
                UpdatePosition(j,childPosition,ref positionChanged,ref playAction);
                #endregion

                #region UpdateSprite
                UpdateSprite(j, playAction, changeSpeedFlag, actionSpeed, overrideAlpha, visible, alpha);
                #endregion
            }
            #endregion
        }

        private void UpdateSprite(int j, EAnimationType playAction, bool changeSpeedFlag, float actionSpeed, bool overrideAlpha, bool visible, float alpha)
        {
            bool changeAction = playAction != EAnimationType.none;
            var action = GetActionByEnum(playAction);
            //渲染

            var animSpriteData = childData.animSpriteData[j];
            animSpriteData.changeAlphaFlag = changeAction;
            if (changeAction)
            {
                var newAction = (int)action;
                animSpriteData.changeAnimationFlag = animSpriteData.animationIndex != newAction;
                animSpriteData.animationIndex = newAction;
            }
            else
            {
                animSpriteData.changeAnimationFlag = false;
            }

            if (changeSpeedFlag)
            {
                animSpriteData.animationSpeed = actionSpeed;
            }

            animSpriteData.changeAlphaFlag = overrideAlpha;
            if (overrideAlpha)
            {
                animSpriteData.alpha = alpha;
                childData.alpha[j] = alpha;
            }

            animSpriteData.forward = childData.forward[j];
            animSpriteData.position = childData.position[j];
            if (!visible)
            {
                animSpriteData.visible = false;
            }
            childData.animSpriteData[j] = animSpriteData;
        }

        private void UpdatePosition(int j,Vector3 childPosition,ref bool positionChanged,ref EAnimationType playAction)
        {
            //==========计算位置
            float moveNeedTime = childData.moveNeedTime[j];
            if (moveNeedTime != 0)//说明是再移动位置，或者变阵
            {
                positionChanged = true;
                float moveTime = realTime - childData.moveStartTime[j];
                float percent = moveTime / moveNeedTime;
                if (percent < 0)
                {
                    //if (playAction == EAnimationType.none)
                    {
                        playAction = EAnimationType.ani_Stand_Idle;
                    }

                    childPosition = childData.position[j];
                }
                else if (percent < 1)
                {
                    if (playAction == EAnimationType.none)
                    {
                        playAction = EAnimationType.ani_Run;
                    }
                    childPosition = Vector3.Lerp(childData.startMovePosition[j],
                        childData.targetMovePosition[j], percent);
                }
                else
                {
                    childPosition = childData.targetMovePosition[j];
                    childData.moveNeedTime[j] = 0;
                    if (playAction == EAnimationType.none)
                    {
                        playAction = EAnimationType.ani_Stand_Idle;
                    }
                }
            }

            if (positionChanged)
            {
                //==============更新位置
                childData.position[j] = childPosition;
            }
        }

        private void UpdateForward(int originTargetDirection, ref int targetDirection, int j)
        {
            //旋转
            if (originTargetDirection != targetDirection && childData.rotateStartTime[j] <= 0)
            {
                childData.rotateStartTime[j] = realTime;
            }
            childData.targetDirection[j] = targetDirection;
            if (childData.rotateStartTime[j] > 0)
            {
                var originDirection = childData.direction[j];
                if (originDirection != targetDirection)
                {
                    //判断旋转方向
                    //判断方法，目标是否在我和我+4的范围内
                    var change = 1;
                    if (Mathf.Abs(originDirection - targetDirection) > 16)
                    {
                        targetDirection = targetDirection + 32;
                    }
                    var diff = targetDirection - originDirection;
                    if (diff > 0 && diff <= 32)
                    {
                        change = 1;
                    }
                    else
                    {
                        change = -1;
                    }

                    var timeDiff = realTime - childData.rotateStartTime[j];
                    var frameCount = (int)(timeDiff / (1 / 120f));
                    if (frameCount >= MarchSequareConstant.RotateFrameSpeed)
                    {
                        childData.rotateStartTime[j] = realTime;
                        var newDirection = (originDirection + change) % 32;
                        if (newDirection < 0)
                        {
                            newDirection += 32;
                        }
                        var fixedForward = directions[newDirection];
                        childData.direction[j] = newDirection;
                        childData.forward[j] = fixedForward;
                    }
                }
                else
                {
                    childData.forward[j] = directions[targetDirection];
                    childData.rotateStartTime[j] = 0;
                }
            }
            else
            {
                //服务器推送瞬移时会造成转身开始时间丢失的问题，因此要额外检查一次
                var originDirection = childData.direction[j];
                if (originDirection != targetDirection)
                {
                    childData.direction[j] = targetDirection;
                    childData.forward[j] = directions[targetDirection];
                }
            }
        }

        private float3 GetFixedDirectionByForward(Vector3 forward, ref int index)
        {
            var angle = PveUtils.GetAngle(Vector3.forward, forward) + 5.625f;
            if (angle < 0)
            {
                angle += 360;
            }
            else if (angle > 360)
            {
                angle = angle % 360;
            }
            index = (int)(angle / 11.25f);
            if (index < 0 || index >= directions.Length)
            {
                index = 0;
                UnityEngine.Debug.LogError($"angle : {angle}");
            }
            return directions[index];
        }

        public float3 GetUnitInSquarePositionOffset(int i, float3 parentForward, int formationId, int count, int turnState, out int finalPosIndex, int formationPositionIndexOffset, bool isBattle = false, int parentIndex = -1)
        {
            //count * (count - 1)/2 为 当前数量士兵索引列表的偏移量 
            //formationPositionIndexOffset 为当前阵型所用的第几套变阵 对应配表rts_formation_soldierIndex表 formationPositionIndexOffset值只会为1，5，9...
            //(formationPositionIndexOffset-1) / 4 为第几套 
            // 4 * 18 * 17 / 2; 代表 变阵整体的偏移量 算法为 4（4套变阵） * 18 （1 + 17 首项加末项） * 17（项数） /2
            int idx = count * (count - 1) / 2 + i + (formationPositionIndexOffset - 1) / 4 * 4 * 18 * 17 / 2;
            int index = 0;
            int offset = 0;
            switch (turnState)
            {
                //18 * 17 / 2 为一套变阵内的偏移量 
                case 0:
                    offset = 0;//18 * 17 / 2 * 0;
                    finalPosIndex = i;
                    index = SoldierPositionIndexArrays[idx + offset];
                    break;
                case 1:
                    offset = 18 * 17 / 2 * 1;
                    index = SoldierPositionIndexArrays[idx + offset];
                    finalPosIndex = index;
                    break;
                case 2:
                    offset = 18 * 17 / 2 * 2;
                    index = SoldierPositionIndexArrays[idx + offset];
                    finalPosIndex = index;
                    break;
                case 3:
                    offset = 18 * 17 / 2 * 3;
                    index = SoldierPositionIndexArrays[idx + offset];
                    finalPosIndex = index;
                    break;
                default:
                    offset = 0;
                    index = SoldierPositionIndexArrays[idx + offset];
                    finalPosIndex = i;
                    break;
            }
            var head = localPositionIndex[formationId];
            var positionIndex = head + index;
            float3 relativePos;
            if (positionIndex >= battlePositions.Length)
            {
                relativePos = float3.zero;
            }
            else
            {
                if (isBattle)
                {
                    relativePos = battlePositions[head + index];
                }
                else
                {
                    relativePos = normalPositions[head + index];
                }
            }
            //if (parentIndex!=-1)
            //{
            //    Debug.LogError($"index:{parentIndex} turnState = {turnState} ");
            //}

            var angle = PveUtils.GetAngle(Vector3.forward, parentForward);
            relativePos = Quaternion.AngleAxis(angle, Vector3.up) * relativePos;
            return relativePos;
        }

        public SPRITE_ACTION_ENUM GetActionByEnum(EAnimationType trigger)
        {
            SPRITE_ACTION_ENUM actionType;
            switch (trigger)
            {
                case EAnimationType.ani_Stand_Idle:
                    actionType = SPRITE_ACTION_ENUM.IDLE;
                    break;
                case EAnimationType.ani_Stand_Shoot_Process:
                    actionType = SPRITE_ACTION_ENUM.ATTACK;
                    break;
                case EAnimationType.ani_Run:
                    actionType = SPRITE_ACTION_ENUM.RUN;
                    break;
                case EAnimationType.ani_Walk:
                    actionType = SPRITE_ACTION_ENUM.WALK;
                    break;
                case EAnimationType.ani_Dead:
                    actionType = SPRITE_ACTION_ENUM.DEAD;
                    break;
                case EAnimationType.HitFly:
                    actionType = SPRITE_ACTION_ENUM.HitFly;
                    break;
                default:
                    actionType = SPRITE_ACTION_ENUM.IDLE;
                    break;
            }

            return actionType;
        }

        private bool CanChildChangeStatus(int currentState)
        {
            return currentState != Enum_ChildState_Dead && currentState != Enum_ChildState_ReadyToDead &&
                   currentState != Enum_ChildState_Escape;
        }

        private float Random(int index, float min, float max)
        {
            return math.lerp(min, max, ((index + frameCount) % 12) / 12f);
        }
    }
}
